package com.hb.trade.server.project.section.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hb.core.pojo.enums.CommonTypeEnum;
import com.hb.core.pojo.enums.ProjectTypeEnum;
import com.hb.core.pojo.enums.SectionStatusEnum;
import com.hb.core.pojo.project.notice.dto.NoticeDTO;
import com.hb.core.pojo.project.notice.dto.NoticeLimitPriceDTO;
import com.hb.core.pojo.project.proj.entity.AbstractProject;
import com.hb.core.pojo.project.proj.enums.BidWayEnum;
import com.hb.core.pojo.project.section.dto.BidSectionDTO;
import com.hb.trade.server.project.section.service.status.CalSectionStatus;
import com.hb.core.pojo.project.section.entity.BidSection;
import com.hb.trade.server.project.proj.service.ProjectService;
import com.hb.trade.server.project.section.service.raw.BidSectionService;
import org.fzzn.core.model.enums.LogicEnum;
import org.fzzn.core.util.Enums;

import java.util.Collection;
import java.util.List;
import java.util.Map;

public class BidSectionManager extends BidSectionDTO {

    /**
     * 获取最高限价信息
     *
     * @return
     */
    public NoticeLimitPriceDTO.LimitPriceDto getLimitPriceConfigIns() {
        if (StrUtil.isEmpty(this.getLimitConfigInfo())) {
            return new NoticeLimitPriceDTO.LimitPriceDto();
        }
        return JSONUtil.toBean(this.getLimitConfigInfo(), NoticeLimitPriceDTO.LimitPriceDto.class);
    }

    /**
     * @param notice:       公告对象
     * @param notFixedFlag: 是否非固定金额
     * @Description:
     * @Author: zhongdl
     * @Date:2021/12/8 13:40
     * @return:
     **/
    public void fillNoticeField(NoticeDTO notice, boolean notFixedFlag) {
        this.setBillingMethod(notice.getBillingMethod());//计费方式
        this.setCollectionMethod(notice.getCollectionMethod());//收取方式
        this.setGuaranteeFlag(notice.getGuaranteeFlag());//是否支持保函
        if (notFixedFlag) {
            this.setBondStr(notice.getBond());
        }

    }

    /**
     * 更改标段状态
     * 更新当前标段的状态
     * 该方法会更新数据库
     */
    public void refreshBidSection() {
        refreshBidSection(true);
    }

    /**
     * 更改标段状态
     * 更新当前标段的状态
     *
     * @param isSave 是否保存数据库
     */
    public void refreshBidSection(boolean isSave) {
        // 获取所有的标段状态判断逻辑处理service
        Map<String, CalSectionStatus> beans = SpringUtil.getBeansOfType(CalSectionStatus.class);
        Collection<CalSectionStatus> values = beans.values();

        // 按照标段状态的顺序阶段排序
        List<CalSectionStatus> statuses = CollUtil.list(false, values);
        CollUtil.sort(statuses, (item1, item2) -> ObjectUtil.compare(item1.getSort(), item2.getSort()));

        for (CalSectionStatus value : statuses) {
            /* 如果当前状态已经大于等于该状态值了, 则不进行判断直接跳过 start */
            // 标段当前状态
            Long currentSectionStatus = this.getSectionStatus();

            // 判断是否匹配当前状态
            boolean with = value.with(currentSectionStatus);
            if (!with) {
                continue;
            }
            /* 如果当前状态已经大于等于该状态值了, 则不进行判断直接跳过 end */

            // 获取当前项目的实际标段状态, 该值若返回null, 表示未到达该状态阶段
            Long nextCurrent = value.getSectionStatus(this);
            if (null == nextCurrent) {
                break;
            }
            this.setSectionStatus(nextCurrent);
        }

        if (isSave) {
            // 将标段状态保存数据库
            BidSectionService bidSectionService = SpringUtil.getBean(BidSectionService.class);
            bidSectionService.updateById(this);
        }
    }

    /**
     * 获取当前标段所在项目的招标方式为公开还是邀请
     *
     * @return 招标方式枚举
     */
    public CommonTypeEnum getCommonTypeEnum() {
        ProjectService projectService = SpringUtil.getBean(ProjectService.class);
        return projectService.getCommonType(this.getProjectId());
    }

    /**
     * 获取当前标段状态的枚举
     *
     * @return
     */
    public SectionStatusEnum getSectionStatusEnum() {
        Long sectionStatus = getSectionStatus();
        return SectionStatusEnum.getIns(sectionStatus);
    }

    /**
     * 获取当前标段所在项目的招标方式
     */
    public BidWayEnum getBidWayEnum() {
        ProjectService projectService = SpringUtil.getBean(ProjectService.class);
        AbstractProject project = projectService.getById(getProjectId());
        if (project == null) {
            return null;
        }
        return Enums.of(BidWayEnum.class, project.getBidWay());
    }

    /**
     * @Description: 填写招标文件基本信息字段
     * @Author: zhongdl
     * @Date:2021/12/10 13:49
     **/
    public void fillBidFileInfo() {
        ProjectService projectService = SpringUtil.getBean(ProjectService.class);
        AbstractProject abstractProject = projectService.getById(getProjectId());
        BeanUtil.copyProperties(abstractProject, this);

        //项目类型
        setProjectTypeName(Enums.nameOf(ProjectTypeEnum.class, getProjectType()));
        //招标方式
        setBidWayName(Enums.nameOf(BidWayEnum.class, getBidWay()));
        //缴纳保证金
        setBondFlagName(Enums.nameOf(LogicEnum.class, getBond()));
    }

    /**
     * 查询标段列表时增加不同的查询条件
     *
     * @param wrapper
     * @param values
     */
    public void buildQueryType(QueryWrapper<BidSection> wrapper, Object... values) {
        Integer queryType = getQueryType();
        if (queryType == null) {
            return;
        }
        switch (queryType) {
            // 查询没有发布过公告的标段信息
            case 1:
                // 这里没解决wrapper调用notExists方法后进行参数注入的问题
                // 因为项目ID是直接拼接到sql中的, 所以在这里查一下项目数据作为防止sql注入的验证
                // 能查询到项目信息, 就算这个参数正常
                // 进入到这个分支, 参数一定是项目ID
                ProjectService projectService = SpringUtil.getBean(ProjectService.class);
                QueryWrapper<AbstractProject> queryWrapper = AbstractProject.wrapper();
                queryWrapper.eq("id", values[0]);
                long count = projectService.count(queryWrapper);

                if (count > 0) {
                    wrapper.notExists("select 1 from trade_notice_bid_section nbs \n" +
                            "left join trade_notice tn ON nbs.notice_id =tn.id \n" +
                            "left join trade_bid_section tbs ON nbs.section_id =tbs.id \n" +
                            "WHERE tbs.project_id ='" + values[0] + "' AND tn.notice_nature ='1'\n" +
                            "AND nbs.section_id = trade_bid_section.id");
                }
                break;
            case 2:
                // 参数为招标文件ID
                wrapper.isNull("file_id");
                break;
            default:
                break;
        }
    }

    /**
     * 获取当前标段的项目信息
     *
     * @return
     */
    public AbstractProject getProjectInfo() {
        Long id = getId();
        if (id == null) {
            id = getSectionId();
        }
        if (id == null) {
            return null;
        }
        BidSectionService sectionService = SpringUtil.getBean(BidSectionService.class);
        BidSection section = sectionService.getById(id);
        ProjectService projectService = SpringUtil.getBean(ProjectService.class);
        return projectService.getByPrimaryKey(section.getProjectId());
    }
}
